#!/usr/bin/python
# ^_^ coding:utf8 ^_^

import sys
import threadpool
from libs.log import logger
from libs.loader import load_modules


modules = list()
progress = {'finish': 0, 'total':0, 'interval': 0}


def print_progress():
    if progress['finish'] % progress['interval'] == 0 or \
       progress['finish']==progress['total']:
        logger.info('Progress: {}/{}'.format(progress['finish'], progress['total']))


def set_total(total):
    progress['total'] = total
    progress['interval'] = 10**(len(str(progress['total']))-1)


def call_back(work_request, _):
    progress['finish'] += 1
    print_progress()


def generation_argvs(scripts, targets):
    argvs = list()
    for script in scripts:
        for target in targets:
            argvs.append(((script, target), None))
    return argvs


def exploit(script, target):
    ret = modules[script].poc(target)
    if isinstance(ret, bool) and ret:
        sys.stdout.write('{}\n'.format(target))
    elif isinstance(ret, list) or isinstance(ret, set):
        for item in ret:
            sys.stdout.write('{}\n'.format(item))
    elif ret == None or ( isinstance(ret, bool) and not ret ):
        pass
    else:
        sys.stdout.write('{}\n'.format(ret))


def run(scripts, targets, threads):
    global modules
    modules = load_modules(scripts)

    logger.info('Start execution ...')
    set_total(len(scripts) * len(targets))
    print_progress()

    pool = threadpool.ThreadPool(threads)
    argvs = generation_argvs(scripts, targets)
    requests = threadpool.makeRequests(exploit, argvs, call_back)
    [pool.putRequest(req) for req in requests]
    pool.wait()
    pool.dismissWorkers(threads)

    logger.success('Completed.')
